package team.zero.lemon.module.workflow.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.zero.lemon.common.exception.CustomException;
import team.zero.lemon.common.service.CrudService;
import team.zero.lemon.module.workflow.dao.IActivityDao;
import team.zero.lemon.module.workflow.entity.Activity;
import team.zero.lemon.module.workflow.entity.Enum.ActivityType;
import team.zero.lemon.module.workflow.entity.Enum.HandleResult;
import team.zero.lemon.module.workflow.entity.NextActivity;
import team.zero.lemon.module.workflow.entity.Parameter.Next;
import team.zero.lemon.module.workflow.entity.Rule;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by bolin on 2016/11/16.
 */
@Service
public class ActivityService extends CrudService<IActivityDao, Activity> {
    @Autowired
    private RuleService ruleService;
    @Autowired
    private ParticipantService participantService;

    /*
    根据模板获取所有的活动
     */
    public List<Activity> findByTemplateId(int templateId) {
        try {
            return dao.findByTemplateId(templateId);
        } catch (Exception exc) {
            throw new CustomException(exc);
        }
    }

    /*
    获取开始活动节点
     */
    public List<Activity> findStartActivityByTemplateId(int templateId) {
        try {
            return dao.findStartActivityByTemplateId(templateId);
        } catch (Exception exc) {
            throw new CustomException(exc);
        }
    }

    /*
    根据规则获取下一步活动节点
     */
    public Activity findNextActivityByRuleId(Integer ruleId) {
        try {
            return dao.findNextActivityByRuleId(ruleId).get(0);
        } catch (Exception exc) {
            throw new CustomException(exc);
        }
    }

    /*
    获取下一步活动节点
     */
    public NextActivity findNextActivitys(Integer activityId, Integer orgId, String expression) {
        try {
            NextActivity nextActivity = new NextActivity();
            nextActivity.getForward().addAll(findNextActivitys(null, activityId, orgId, expression));
            nextActivity.getBack().addAll(findBackActivitys(activityId));
            return nextActivity;
        } catch (Exception exc) {
            throw new CustomException(exc);
        }
    }

    /*
    表达式：state=1 || money<500
    参数：  state:1|money:500
     */
    private List<Activity> findNextActivitys(List<Integer> ruleIds, Integer activityId, Integer orgId, String expression) {
        //先获取给定活动的所有后继规则
        //规则服务
        List<Activity> resultValue = new ArrayList<Activity>();
        List<Rule> rules = ruleService.findRuleByFromActivityIdRuleType(activityId, 0);
        if (!"".equals(expression)) {
            String[] expressionArray = expression.split("\\|");
            boolean result = false;
            for (Rule rule : rules) {
                String ruleExpression = rule.getExpression();
                if (!(result = (ruleExpression == null || "".equals(ruleExpression)))) {
                    int flag = 0;
                    while (flag < expressionArray.length) {
                        String tmp = expressionArray[flag];
                        for (int i = flag + 1; i < expressionArray.length; i++) {
                            if ((expressionArray[i].split(":")[0]).length() > (tmp.split(":")[0]).length()) {
                                expressionArray[flag] = expressionArray[i];
                                expressionArray[i] = tmp;
                                tmp = expressionArray[flag];
                            }
                        }
                        ruleExpression = ruleExpression.replace(expressionArray[flag].split(":")[0], expressionArray[flag].split(":")[1]);
                        ++flag;
                    }
                    try {
                        ScriptEngineManager manager = new ScriptEngineManager();
                        ScriptEngine engine = manager.getEngineByName("js");
                        result = (boolean) engine.eval(ruleExpression);
                    } catch (Exception exc) {
                        result = false;
                    }
                }
                if (result) {
                    Activity activity = findById(rule.getToActivityId());
                    if (activity != null) {
                        if (ruleIds != null) {
                            activity.getRuleIds().addAll(ruleIds);
                        }
                        activity.getRuleIds().add(rule.getId());
                        if (activity.getActivityType() == ActivityType.condition.ordinal()) {
                            resultValue.addAll(findNextActivitys(activity.getRuleIds(), activity.getId(), orgId, expression));
                        } else {
                            resultValue.add(activity);
                            activity.getParticipantses().addAll(participantService.findParticipantsByActivityIdOrgId(activity.getId(), orgId));
                        }
                    }
                }
            }
        } else {
            for (Rule rule : rules) {
                Activity activity = findById(rule.getToActivityId());
                if (activity != null) {
                    if (ruleIds != null) {
                        activity.getRuleIds().addAll(ruleIds);
                    }
                    activity.getRuleIds().add(rule.getId());
                    if (activity.getActivityType() == ActivityType.condition.ordinal()) {
                        resultValue.addAll(findNextActivitys(activity.getRuleIds(), activity.getId(), orgId, expression));
                    } else {
                        resultValue.add(activity);
                        activity.getParticipantses().addAll(participantService.findParticipantsByActivityIdOrgId(activity.getId(), orgId));
                    }
                }
            }
        }
        return resultValue;
    }

    /*
    获取回退节点
    表达式：state=1 || money<500
    参数：  state:1|money:500
    */
    private List<Activity> findBackActivitys(Integer activityId) {
        //先获取给定活动的所有后继规则
        //规则服务
        List<Activity> nextActivity = new ArrayList<Activity>();
        List<Rule> rules = ruleService.findRuleByFromActivityIdRuleType(activityId, 1);

        for (Rule rule : rules) {
            Activity activity = findById(rule.getToActivityId());
            if (activity != null) {
                activity.getRuleIds().add(rule.getId());
                if (!nextActivity.contains(activity)) nextActivity.add(activity);
            }
        }
        return nextActivity;
    }
}
